package com.hiray.wanandroid.ui.page

import androidx.compose.animation.*
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.*
import androidx.paging.compose.collectAsLazyPagingItems
import coil.compose.rememberImagePainter
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.HorizontalPagerIndicator
import com.google.accompanist.pager.rememberPagerState
import com.hiray.wanandroid.R
import com.hiray.wanandroid.data.WanViewModel
import com.hiray.wanandroid.net.response.FeedTag
import com.hiray.wanandroid.net.response.HomeBanner
import com.hiray.wanandroid.net.response.HomeFeed
import kotlinx.coroutines.launch


@ExperimentalAnimationApi
@ExperimentalUnitApi
@ExperimentalPagerApi
@Composable
fun MainPage(viewModel: WanViewModel) {
    LaunchedEffect(key1 = viewModel.banners, block = {
        viewModel.fetchBanner()
    })
    Box {
        val scope = rememberCoroutineScope()
        val lazyItems = viewModel.feedFlow.collectAsLazyPagingItems()
        val lazyListState = rememberLazyListState()
        LazyColumn(state = lazyListState) {
            items(lazyItems.itemCount + 1) { index ->
                if (index == 0) {
                    TopBanner(viewModel.banners)
                } else
                    HomeFeedItem(lazyItems[index - 1]!!)
            }
        }
        var floatingActionButtonVisible by remember { mutableStateOf(false) }
        floatingActionButtonVisible = lazyListState.firstVisibleItemIndex > 4
        AnimatedVisibility(
            visible = floatingActionButtonVisible, modifier = Modifier
                .align(Alignment.BottomEnd)
                .padding(bottom = 16.dp, end = 16.dp),
            enter = fadeIn() + slideIn(initialOffset = { IntOffset(0, it.height) }),
            exit = fadeOut() + slideOut(targetOffset = { IntOffset(0, it.height) })
        ) {
            FloatingActionButton(onClick = {
                floatingActionButtonVisible = false
                scope.launch { lazyListState.scrollToItem(0) }
            }) {
                Icon(
                    imageVector = ImageVector.vectorResource(id = R.drawable.back_to_top),
                    contentDescription = "",
                    Modifier.size(24.dp),
                    tint = Color.White
                )
            }
        }

    }
}

@ExperimentalPagerApi
@Composable
fun TopBanner(banners: List<HomeBanner>) {
    if (banners.isNotEmpty()) {
        Box(modifier = Modifier.fillMaxWidth()) {
            val pagerState = rememberPagerState(pageCount = banners.size, 0, 0f, banners.size, true)
            HorizontalPager(state = pagerState) { page ->
                TopBannerItem(banners[page])
            }
            HorizontalPagerIndicator(
                pagerState = pagerState,
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .padding(16.dp)
            )
        }
    }
}

@Composable
fun TopBannerItem(homeBanner: HomeBanner) {
    Image(
        painter = rememberImagePainter(homeBanner.imageUrl),
        contentDescription = homeBanner.title,
        Modifier
            .fillMaxWidth()
            .height(140.dp),
        contentScale = ContentScale.FillWidth
    )
}

@ExperimentalUnitApi
@Composable
fun HomeFeedItem(feed: HomeFeed) {
    Box(
        Modifier
            .fillMaxWidth()
            .clickable {
                //todo
            }) {
        Column(Modifier.padding(horizontal = 12.dp, vertical = 12.dp)) {
            // tags
            Row {
                if (feed.isPinned) {
                    Tag("置顶", textColor = Color.Red, borderColor = Color.Red)
                    Spacer(
                        modifier = Modifier
                            .align(Alignment.CenterVertically)
                            .width(8.dp)
                    )
                }
                feed.tags.forEach { tag ->
                    Tag(
                        name = tag.name,
                        modifier = Modifier
                            .align(Alignment.CenterVertically),
                        textColor = Color.Gray,
                        borderColor = Color.Gray
                    )
                    Spacer(
                        modifier = Modifier
                            .align(Alignment.CenterVertically)
                            .width(8.dp)
                    )
                }
                // author / shareUser
                if (feed.author.isNotEmpty())
                    Tag(
                        name = feed.author,
                        textColor = Color.Magenta,
                        borderColor = Color.Magenta
                    )
                else if (feed.shareUser.isNotEmpty())
                    Tag(
                        name = feed.shareUser,
                        textColor = Color.DarkGray,
                        borderColor = Color.DarkGray
                    )

            }
            Text(
                feed.unescapedTitle(),
                Modifier
                    .padding(top = 10.dp)
                    .fillMaxSize(0.88f),
                fontSize = 15.sp,
                maxLines = 2,
                overflow = TextOverflow.Ellipsis
            )
        }

        Box(
            modifier =
            Modifier
                .align(Alignment.CenterEnd)
                .fillMaxSize(0.12f),
            contentAlignment = Alignment.Center
        ) {
            Image(
                painter = painterResource(R.drawable.like),
                contentDescription = "喜欢",
                modifier = Modifier
                    .width(15.dp)
                    .height(15.dp),
                colorFilter = if (feed.liked) ColorFilter.tint(Color.Red) else null
            )
        }

        Box(
            modifier = Modifier
                .padding(start = 12.dp, end = 12.dp)
                .align(Alignment.BottomCenter)
        ) {
            Divider(
                Modifier
                    .fillMaxWidth()
                    .height(0.5.dp)
                    .background(Color.LightGray)
            )
        }
    }
}

@ExperimentalUnitApi
@Composable
fun Tag(
    name: String,
    corner: Dp = 4.dp,
    textColor: Color,
    borderColor: Color,
    modifier: Modifier = Modifier
) {
    Text(
        text = name,
        Modifier
            .border(
                BorderStroke(0.5.dp, SolidColor(borderColor)),
                RoundedCornerShape(corner)
            )
            .padding(2.dp)
            .then(modifier),
        color = textColor,
        textAlign = TextAlign.Center,
        fontSize = TextUnit(10f, TextUnitType.Sp)
    )
}

@ExperimentalUnitApi
@Composable
@Preview(showBackground = true)
fun PreviewHomeFeedItem() {
    HomeFeedItem(
        feed = HomeFeed(
            "使用 APT 开发组件化框架的若干细节问题",
            "",
            "",
            "rengwuxian",
            "default source",
            "13 hours ago",
            tags = listOf(
                FeedTag("原创", "/article/id/12")
            ),
            liked = true
        ).apply { isPinned = true }
    )
}
